/*------------------------------------------------------------------------
//                          Project CommonLib                           //
------------------------------------------------------------------------*/
#pragma once

#include <map>
template<typename T, typename DATA1, typename DATA2, typename DATA3>
class LogicPtrFunc
{
public:        
    typedef void (T::*PF_FUNCTION)(DATA1, DATA2, DATA3);        
	typedef typename std::map<DWORD, PF_FUNCTION>	PFUNC_MAP;
        
public:
    LogicPtrFunc()
    {
        Clear(); 
    };

    virtual ~LogicPtrFunc()
    {
        Clear();
    };

    virtual bool Register()=0;
    virtual void OnHandleMsg(const DWORD& index, DATA1 data1, DATA2 data2, DATA3 data3)=0;

	virtual bool Excute(const DWORD& index, DATA1 data1, DATA2 data2, DATA3 data3)			
    {
        if(IsExist(index))
        {                
            (((T*)this)->*m_mpFunc[index])(data1, data2, data3);
                return true;
        }
            
        OnHandleMsg( index, data1, data2, data3);
        return false;
    }

    virtual bool Insert(DWORD index, PF_FUNCTION pfFunc)
    {
        if( !IsExist(index) )
        {
            m_mpFunc.insert( PFUNC_MAP::value_type(index, pfFunc));            
            return true;
        }
        return false;
    }

    bool IsExist(const DWORD& index)
    {
        return (m_mpFunc.find(index)!=m_mpFunc.end()?true:false);
    }

private:        
    void Clear()
    {
        if( !m_mpFunc.empty())
            m_mpFunc.clear();
    }

    PFUNC_MAP	m_mpFunc;
};

#define LOGIC_CLASS(classname) \
	public: \
		typedef classname LogicPtr

#define REG_PTRFUNC( _func ) \
	void _func(DWORD, DWORD, DWORD)

#define INSERT_PTR_FUNC(type) \
	if(!Insert( e##type,  &LogicPtr::type)) return false;

/*------------------------------------------------------------------------

------------------------------------------------------------------------*/
 